package com.winit.openapi.wop.inbound.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.SearchOperator;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.Sort.Direction;
import com.winit.common.query.filter.SearchFilterHelper;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.warehouse.WarehouseService;
import com.winit.erp.spi.warehouse.command.WarehouseCommand;
import com.winit.erp.spi.warehouse.vo.Warehouse;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.ValidateUtil;
import com.winit.openapi.wop.inbound.constant.WHInboundConstant;
import com.winit.pms.spi.v2.common.PmsConstants;
import com.winit.pms.spi.v2.instance.pscInstance.ProductInstanceService;
import com.winit.pms.spi.v2.instance.pscInstance.command.ProductQueryCommand;
import com.winit.pms.spi.v2.instance.pscInstance.vo.ProductInstance;
import com.winit.pms.spi.winit.LogisticsdistService;
import com.winit.pms.spi.winit.WinitDeliveryWayService;
import com.winit.pms.spi.winit.WinitPostService;
import com.winit.pms.spi.winit.WinitProductService;
import com.winit.pms.spi.winit.WinitRuleService;
import com.winit.pms.spi.winit.WinitSlaService;
import com.winit.pms.spi.winit.command.LogisticsDistFindCommand;
import com.winit.pms.spi.winit.command.WinitPostFindCommand;
import com.winit.pms.spi.winit.command.WinitProductFindCommand;
import com.winit.pms.spi.winit.command.WinitProductQueryBySellerCommand;
import com.winit.pms.spi.winit.command.WinitSlaFindCommand;
import com.winit.pms.spi.winit.vo.LogisticsDist;
import com.winit.pms.spi.winit.vo.WinitPost;
import com.winit.pms.spi.winit.vo.WinitProduct;
import com.winit.pms.spi.winit.vo.WinitSla;

@Controller
@RequestMapping(value = "/winit/wh/pms")
public class WHInboundProductController extends BaseController {

    private Logger                  logger = LoggerFactory.getLogger(WHInboundProductController.class);

    @Resource
    private LogisticsdistService    logisticsdistService;

    @Resource
    private WinitProductService     productService;

    @Resource
    private WarehouseService        warehouseService;

    @Resource
    private WinitSlaService         winitSlaService;

    @Resource
    private WinitPostService        winitPostService;

    @Resource
    private WinitRuleService        winitRuleService;

    @Resource
    private WinitDeliveryWayService winitDeliveryWayService;

    @Resource
    private ProductInstanceService  productInstanceService;

    @RequestMapping(value = "/getWinitProducts")
    public String list(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        List<Map<String, String>> dataList = new ArrayList<Map<String, String>>();
        // 获取参数
        JSONObject json = JSONObject.parseObject(requestMsg.getData().toString());
        if (null == json) {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        ValidateUtil.validNotNull(json, "productType");
        ValidateUtil.validMaxLength(json, "productType", 20, true);
        if (!WHInboundConstant.ProductType.isValidOrderType(json.getString("productType"))) {
            throw new ApiException(ErrorCode.FEILD_NOT_MATCH, "productType");
        }
        if (json.containsKey("warehouseID") && !StringUtils.isBlank(json.getString("warehouseID"))) {
            Long warehouseID = Long.parseLong(json.getString("warehouseID"));
            // 根据Id获取仓库
            Warehouse warehouse = getWarehouse(warehouseID);
            // 根据邮编获取物流分区
            List<Long> logisticsIdList = getLogisticsIdList(warehouse.getPostal());
            // 过滤非仓库的物流分区
            logisticsIdList = getWHLogisticsIdList(logisticsIdList);
            if (logisticsIdList.size() > 0) {
                // 获取产品Id列表
                List<Long> productIdList = getWinitProductIdList(logisticsIdList);
                if (productIdList.size() > 0) {
                    WinitProductFindCommand productCommand = new WinitProductFindCommand();
                    Searchable searchable = Searchable.newSearchable();
                    // 查询所有的值
                    searchable.setPage(0, Integer.MAX_VALUE);
                    // 按组织ID查询
                    searchable.and(SearchFilterHelper.newCondition("ORGANIZATION_ID",
                        SearchOperator.eq,
                        CommandContext.getContext().getOrgId()));
                    searchable.and(SearchFilterHelper.newCondition("WINIT_PRODUCT_ID",
                        SearchOperator.in,
                        convertIn(productIdList)));
                    productCommand.setSearchable(searchable);
                    Page<WinitProduct> page = productService.findProduct(productCommand);
                    if (null != page && page.getContent() != null && page.getContent().size() > 0) {
                        for (WinitProduct product : page.getContent()) {
                            Map<String, String> r1 = new HashMap<String, String>();
                            r1.put("productCode", product.getCode());
                            r1.put("productName", product.getName());
                            r1.put("description", product.getDescription());
                            dataList.add(r1);
                        }
                    }
                }
            }
        } else {
            WinitProductQueryBySellerCommand command = new WinitProductQueryBySellerCommand();
            command.setCtx(CommandContext.getContext());
            command.setOrganizationId(CommandContext.getContext().getOrgId().longValue());
            // 产品分类名称
            if (ValidateUtil.isNotNull(json, "productType")) {
                command.setProductCatelogName(json.getString("productType"));
            } else {
                // 之前默认类型为ISP
                command.setProductCatelogName(ApiConstant.PRODUCT_CATALOG_ISP);
            }
            if (PmsConstants.PRODUCT_CATEGORY_OSF8.equals(command.getProductCatelogName())) {// 出库
                ProductQueryCommand queryCommand = new ProductQueryCommand();
                queryCommand.setCtx(CommandContext.getContext());
                queryCommand.setTwoCategoryCode(PmsConstants.PRODUCT_CATEGORY_OSF8);
                queryCommand.setBpartnerCode(CommandContext.getContext().getUserId());
                List<ProductInstance> productList = productInstanceService.queryProductList(queryCommand);
                if (null != productList && productList.size() > 0) {
                    for (ProductInstance product : productList) {
                        Map<String, String> r1 = new HashMap<String, String>();
                        r1.put("productCode", product.getCode());
                        r1.put("productName", product.getName());
                        r1.put("description", product.getDescription());
                        dataList.add(r1);
                    }
                }
            } else {
                if (ValidateUtil.isNotNull(json, "productCatalogLv2")) {
                    command.setProductCatalogLv2(json.getString("productCatalogLv2"));
                }
                List<WinitProduct> productList = productService.queryWinitProduct(command);
                if (null != productList && productList.size() > 0) {
                    for (WinitProduct product : productList) {
                        Map<String, String> r1 = new HashMap<String, String>();
                        r1.put("productCode", product.getCode());
                        r1.put("productName", product.getName());
                        r1.put("description", product.getDescription());
                        dataList.add(r1);
                    }
                }
            }
        }
        responseMsg.setData(dataList);
        return SUCCESS;
    }

    /**
     * 根据仓库Id查询仓库
     * 
     * @param warehouseId
     * @return
     */
    private Warehouse getWarehouse(Long warehouseId) {
        // 初始化查询command
        WarehouseCommand command = new WarehouseCommand();
        command.setWarehouseId(warehouseId);
        // 查询仓库信息
        Warehouse warehouse = warehouseService.getWarehouse(command);
        return warehouse;
    }

    /**
     * 根据邮编查询满足条件的物流分区ID
     * 
     * @param postcode
     * @return
     */
    private List<Long> getLogisticsIdList(String postcode) {
        WinitPostFindCommand command = new WinitPostFindCommand();
        // 初始化查询条件seachable
        Searchable searchable = Searchable.newSearchable();
        searchable.and(SearchFilterHelper.newCondition("CODE", SearchOperator.eq, postcode));
        // 查询所有满足条件的数据
        searchable.setPage(0, Integer.MAX_VALUE);
        command.setSearchable(searchable);
        Page<WinitPost> page = winitPostService.findWinitPost(command);
        List<Long> logisticsIdList = new ArrayList<Long>();
        if (null != page && null != page.getContent() && page.getContent().size() > 0) {
            for (WinitPost post : page.getContent()) {
                if (!logisticsIdList.contains(post.getWinitLogisticsdistId())) {
                    logisticsIdList.add(post.getWinitLogisticsdistId());
                }
            }
        }
        return logisticsIdList;
    }

    /**
     * 获取仓库的物流分区
     * 
     * @param logisticsIdList
     * @return
     */
    private List<Long> getWHLogisticsIdList(List<Long> logisticsIdList) {
        List<Long> list = new ArrayList<Long>();
        for (Long id : logisticsIdList) {
            LogisticsDistFindCommand command = new LogisticsDistFindCommand();
            // 初始化查询条件seachable
            Searchable searchable = Searchable.newSearchable();
            searchable.and(SearchFilterHelper.newCondition("WINIT_LOGISTICSDIST_ID", SearchOperator.eq, id));
            // 根据ID查询，结果唯一
            searchable.setPage(0, 1);
            searchable.addSort(new Sort(Direction.DESC, "WINIT_LOGISTICSDIST_ID"));
            command.setSearchable(searchable);
            command.setCtx(CommandContext.getContext());
            Page<LogisticsDist> page = logisticsdistService.findLogisticsDist(command);
            if (null != page && null != page.getContent() && page.getContent().size() > 0) {
                LogisticsDist logisticsDist = page.getContent().get(0);
                if (null != logisticsDist && "Warehouse".equals(logisticsDist.getDistrictType())) {
                    list.add(logisticsDist.getWinitLogisticsdistId());
                } else {
                    logger.info("万邑通产品物流分区不为仓库分区, id:{}", new Object[] { id });
                }
            } else {
                logger.info("万邑通产品物流分区不存在, id:{}", new Object[] { id });
            }
        }
        return list;
    }

    /**
     * 根据物流分区Id获取产品Id
     * 
     * @param logisticsIdList
     * @return
     */
    private List<Long> getWinitProductIdList(List<Long> logisticsIdList) {
        WinitSlaFindCommand command = new WinitSlaFindCommand();
        Searchable searchable = Searchable.newSearchable();
        searchable.and(SearchFilterHelper.newCondition("SLA_BEGIAN", SearchOperator.in, convertIn(logisticsIdList)));
        // 查询所有数据
        searchable.setPage(0, Integer.MAX_VALUE);
        command.setSearchable(searchable);
        Page<WinitSla> page = winitSlaService.findWinitSla(command);
        List<Long> ProductIdList = new ArrayList<Long>();
        if (null != page && null != page.getContent() && page.getContent().size() > 0) {
            for (WinitSla sla : page.getContent()) {
                if (!ProductIdList.contains(sla.getWinitProductId())) {
                    ProductIdList.add(sla.getWinitProductId());
                }
            }
        }
        return ProductIdList;
    }

    /**
     * 拼接查询in条件
     * 
     * @param slaList
     * @return
     */
    private String convertIn(List<Long> slaList) {
        StringBuffer buff = new StringBuffer();
        boolean startFlag = true;
        for (Long logisticId : slaList) {
            if (startFlag) {
                buff.append("(").append(logisticId);
                startFlag = false;
            } else {
                buff.append(",").append(logisticId);
            }
        }
        buff.append(")");
        return buff.toString();
    }

}
